

package com.hazelcast.test.bounce;

import com.hazelcast.config.Config;
import com.hazelcast.core.HazelcastInstance;

import java.util.Arrays;

import static com.hazelcast.test.HazelcastTestSupport.waitAllForSafeState;

/**
 * Default member-side test driver factory. When test driver is {@code ALWAYS_UP_MEMBER}, returns the steady member of
 * the cluster as returned by {@link BounceMemberRule#getSteadyMember()} as test driver. When test driver
 * is {@code MEMBER}, the configured number of test drivers are created. Otherwise, an {@code AssertionError} is thrown.
 */
public class MemberDriverFactory implements DriverFactory {

    @Override
    public HazelcastInstance[] createTestDrivers(BounceMemberRule rule) {
        BounceTestConfiguration testConfiguration = rule.getBounceTestConfig();
        HazelcastInstance[] drivers = new HazelcastInstance[testConfiguration.getDriverCount()];
        switch (testConfiguration.getDriverType()) {
        case ALWAYS_UP_MEMBER:
            Arrays.fill(drivers, rule.getSteadyMember());
            return drivers;
        case MEMBER:
        case LITE_MEMBER:
            for (int i = 0; i < drivers.length; i++) {
                Config driverConfig = getDriverConfig(testConfiguration);
                drivers[i] = rule.getFactory().newHazelcastInstance(driverConfig);
            }
            waitAllForSafeState(drivers);
            return drivers;
        default:
            throw new AssertionError("MemberDriverFactory cannot create test drivers for " + testConfiguration.getDriverType());
        }
    }

    private Config getDriverConfig(BounceTestConfiguration testConfiguration) {
        Config config = getConfig();
        Config driverConfig = config != null ? config : testConfiguration.getMemberConfigSupplier().get();
        if (testConfiguration.getDriverType() == BounceTestConfiguration.DriverType.LITE_MEMBER) {
            driverConfig.setLiteMember(true);
        }
        return driverConfig;
    }

    /**
     * Override this method to provide custom configuration for test drivers
     * <p>
     * When you return <code>null</code> then drivers will use the same
     * configuration as other (non-driver) members.
     */
    protected Config getConfig() {
        return null;
    }
}
